// ==UserScript== // @name 喵课助手 | 网课小工具 // @namespace http://nb.zizizi.top/ // @version 1.1.3 // @description 为各大网课平台提供全自动学习辅助功能,包括视频加速、自动播放、笔记工具等,让您轻松应对各类网络课程 // @author 喵课团队 // @match *://*.edu.cn/* // @match *://*.chaoxing.com/* // @match *://*.zhihuishu.com/* // @match *://*.icve.com.cn/* // @match *://*.cnmooc.org/* // @match *://*.xuetangx.com/* // @match *://*.icourse163.org/* // @match *://*.yuketang.cn/* // @match *://*.mooc.cn/* // @match *://study.163.com/* // @match *://www.bilibili.com/video/* // @match *://v.qq.com/* // @icon http://nb.zizizi.top/miaoke.ico // @grant GM_addStyle // @grant GM_setValue // @grant GM_getValue // @license MIT // ==/UserScript== (function() { 'use strict'; // 工具类 class MiaoKeHelper { constructor() { // 单例模式:检查是否已有实例 if (window.miaokeHelperInstance) { console.log('喵课助手已经实例化,返回现有实例'); return window.miaokeHelperInstance; } // 检查全局是否有面板 if (document.getElementById('miaoke-panel')) { console.log('检测到页面已有喵课助手面板,移除旧面板'); // 尝试移除可能存在的旧的事件监听器 try { const oldPanel = document.getElementById('miaoke-panel'); oldPanel.parentNode.removeChild(oldPanel); } catch (e) { console.error('移除旧面板失败', e); } } // 存储实例到全局 window.miaokeHelperInstance = this; this.version = '1.0'; this.siteName = this.detectSite(); this.playAttempts = {}; // 记录播放尝试次数 this.lastPlayTime = 0; // 最后一次尝试播放的时间 this.isUserPaused = false; // 用户是否主动暂停 // 显示欢迎提示,增强推广效果 this.showFirstTimeWelcome = !GM_getValue('miaokeHelper_welcomed', false); this.init(); // 首次使用显示欢迎提示 if (this.showFirstTimeWelcome) { setTimeout(() => { this.showWelcomeNotification(); GM_setValue('miaokeHelper_welcomed', true); }, 1500); } // 检查更新版本后显示新功能提示 const lastVersion = GM_getValue('miaokeHelper_version', ''); if (lastVersion !== this.version) { setTimeout(() => { this.showUpdateNotification(lastVersion); GM_setValue('miaokeHelper_version', this.version); }, 2000); } // 设置周期性提醒 this.setupPeriodicReminder(); // 添加存储到localStorage,记录已初始化 try { localStorage.setItem('miaokeHelper_initialized', 'true'); localStorage.setItem('miaokeHelper_timestamp', Date.now().toString()); } catch (e) { console.log('无法写入localStorage', e); } } // 检测当前网站 detectSite() { const host = window.location.hostname; if (host.includes('chaoxing.com')) return '超星学习通'; if (host.includes('zhihuishu.com')) return '智慧树'; if (host.includes('icve.com.cn')) return '智慧职教'; if (host.includes('xuetangx.com')) return '学堂在线'; if (host.includes('icourse163.org')) return '中国大学MOOC'; if (host.includes('bilibili.com')) return 'B站视频'; if (host.includes('v.qq.com')) return '腾讯视频'; return '教育平台'; } // 初始化 init() { this.addStyles(); this.createHelperButton(); this.createPanel(); this.setupEvents(); this.listenToHistoryChanges(); console.log(`喵课助手已启动 - ${this.siteName}`); } // 添加样式 addStyles() { const style = document.createElement('style'); style.textContent = ` /* 主容器样式 */ #miaoke-helper-btn { position: fixed; z-index: 9999; right: 20px; top: 100px; width: 60px; height: 60px; border-radius: 50%; background: linear-gradient(135deg, #6a5af9, #d66efd); color: white; text-align: center; line-height: 60px; font-size: 28px; cursor: pointer; box-shadow: 0 4px 20px rgba(106, 90, 249, 0.4); transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); user-select: none; border: 2px solid rgba(255, 255, 255, 0.3); animation: pulseMiaoke 2s infinite; } @keyframes pulseMiaoke { 0% { transform: scale(1); box-shadow: 0 4px 20px rgba(106, 90, 249, 0.4); } 50% { transform: scale(1.1); box-shadow: 0 4px 25px rgba(106, 90, 249, 0.7); } 100% { transform: scale(1); box-shadow: 0 4px 20px rgba(106, 90, 249, 0.4); } } #miaoke-helper-btn:hover { transform: scale(1.1) rotate(5deg); box-shadow: 0 6px 25px rgba(106, 90, 249, 0.6); animation: none; } /* 通知样式 */ .miaoke-notification { position: fixed; bottom: 30px; right: 30px; width: 320px; background: white; border-radius: 12px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15); z-index: 10000; overflow: hidden; animation: slideInRight 0.5s forwards; border: 1px solid rgba(106, 90, 249, 0.2); font-family: 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif; } @keyframes slideInRight { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } } @keyframes slideOutRight { from { transform: translateX(0); opacity: 1; } to { transform: translateX(100%); opacity: 0; } } .notification-header { padding: 15px 20px; background: linear-gradient(135deg, #6a5af9, #d66efd); color: white; font-weight: bold; font-size: 16px; display: flex; justify-content: space-between; align-items: center; } .notification-content { padding: 18px 20px; line-height: 1.5; color: #333; } .notification-footer { padding: 12px 20px; display: flex; justify-content: flex-end; background: #f7f7f7; border-top: 1px solid #eee; } .notification-close { cursor: pointer; padding: 5px 15px; background: #6a5af9; color: white; border-radius: 5px; font-size: 14px; transition: all 0.2s; } .notification-close:hover { background: #d66efd; } .feature-highlight { display: flex; align-items: center; margin: 10px 0; padding: 8px 12px; background: rgba(106, 90, 249, 0.1); border-radius: 6px; } .feature-icon { font-size: 18px; margin-right: 10px; } .share-button { background: linear-gradient(135deg, #6a5af9, #d66efd); color: white; border: none; padding: 10px 15px; border-radius: 5px; cursor: pointer; font-weight: bold; margin-top: 10px; width: 100%; transition: all 0.2s; } .share-button:hover { transform: translateY(-2px); box-shadow: 0 4px 10px rgba(106, 90, 249, 0.3); } /* 主面板样式 */ #miaoke-helper-panel { position: fixed; z-index: 9998; right: 20px; top: 100px; width: 340px; background: rgba(255, 255, 255, 0.95); border-radius: 16px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15); font-family: 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif; transition: all 0.4s cubic-bezier(0.165, 0.84, 0.44, 1); display: none; overflow: hidden; backdrop-filter: blur(10px); border: 1px solid rgba(106, 90, 249, 0.2); transform-origin: top right; } #miaoke-helper-panel.active { display: block; animation: panelFadeIn 0.4s forwards; } @keyframes panelFadeIn { from { opacity: 0; transform: translateY(-20px) scale(0.95); } to { opacity: 1; transform: translateY(0) scale(1); } } /* 面板头部 */ .helper-header { padding: 18px 20px; background: linear-gradient(135deg, #6a5af9, #d66efd); color: white; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid rgba(255, 255, 255, 0.1); } .helper-title { margin: 0; font-size: 18px; font-weight: 600; letter-spacing: 0.5px; display: flex; align-items: center; gap: 8px; } .helper-title:before { content: '🐱'; display: inline-block; font-size: 22px; } .helper-close { cursor: pointer; font-size: 22px; width: 30px; height: 30px; display: flex; align-items: center; justify-content: center; border-radius: 50%; transition: all 0.2s; background: rgba(255, 255, 255, 0.2); } .helper-close:hover { background: rgba(255, 255, 255, 0.3); transform: rotate(90deg); } /* 功能区 */ .helper-content { padding: 20px; max-height: 450px; overflow-y: auto; scrollbar-width: thin; } .helper-content::-webkit-scrollbar { width: 6px; } .helper-content::-webkit-scrollbar-track { background: rgba(0, 0, 0, 0.05); border-radius: 3px; } .helper-content::-webkit-scrollbar-thumb { background: rgba(106, 90, 249, 0.3); border-radius: 3px; } .helper-section { margin-bottom: 24px; padding-bottom: 8px; position: relative; } .section-title { font-size: 16px; font-weight: 600; margin-bottom: 14px; color: #333; border-bottom: 2px solid #eee; padding-bottom: 8px; position: relative; } .section-title:after { content: ''; position: absolute; bottom: -2px; left: 0; width: 50px; height: 2px; background: linear-gradient(90deg, #6a5af9, #d66efd); } .feature-container { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 10px; } .feature-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 10px 16px; background: #f5f5f5; border-radius: 8px; cursor: pointer; font-size: 14px; color: #444; transition: all 0.3s; border: 1px solid #e0e0e0; min-width: 90px; } .feature-btn:before { font-size: 16px; } #auto-play:before { content: '▶️'; } #reading-mode:before { content: '📖'; } #take-notes:before { content: '📝'; } #speed-control:before { content: '⏱️'; } #auto-next:before { content: '⏭️'; } .feature-btn:hover { background: #EEEAFF; border-color: #d1caff; transform: translateY(-2px); box-shadow: 0 4px 12px rgba(106, 90, 249, 0.1); } .feature-btn.active { background: linear-gradient(135deg, #6a5af9, #d66efd); color: white; border-color: transparent; box-shadow: 0 4px 15px rgba(106, 90, 249, 0.3); } /* 设置区域 */ .helper-setting { margin-bottom: 14px; display: flex; justify-content: space-between; align-items: center; padding: 10px 15px; background: #f8f8f8; border-radius: 10px; transition: all 0.3s; border: 1px solid #eee; } .helper-setting:hover { background: #f0f0f0; border-color: #ddd; } .setting-label { font-size: 14px; color: #444; font-weight: 500; } .setting-input { width: 70px; text-align: center; border: 1px solid #ddd; border-radius: 6px; padding: 6px 8px; font-size: 14px; transition: all 0.3s; background: white; } .setting-input:focus { outline: none; border-color: #6a5af9; box-shadow: 0 0 0 3px rgba(106, 90, 249, 0.1); } /* 底部 */ .helper-footer { padding: 12px 15px; background: #f5f5f5; text-align: center; font-size: 12px; color: #666; border-top: 1px solid #eee; } .helper-footer a { color: #6a5af9; text-decoration: none; font-weight: 500; transition: all 0.2s; } .helper-footer a:hover { color: #d66efd; text-decoration: underline; } /* 笔记面板 */ #note-panel { position: fixed; right: 20px; bottom: 20px; width: 340px; height: 300px; background: white; border-radius: 16px; box-shadow: 0 8px 25px rgba(0,0,0,0.15); z-index: 9997; display: none; overflow: hidden; border: 1px solid rgba(106, 90, 249, 0.2); transition: all 0.4s cubic-bezier(0.165, 0.84, 0.44, 1); } #note-panel.active { display: block; animation: notePanelFadeIn 0.4s forwards; } @keyframes notePanelFadeIn { from { opacity: 0; transform: translateY(20px) scale(0.95); } to { opacity: 1; transform: translateY(0) scale(1); } } .note-header { padding: 15px; background: linear-gradient(135deg, #6a5af9, #d66efd); color: white; display: flex; justify-content: space-between; align-items: center; font-size: 16px; font-weight: 600; } .note-content { padding: 15px; height: calc(100% - 110px); } .note-textarea { width: 100%; height: 100%; border: 1px solid #e0e0e0; border-radius: 8px; padding: 10px; resize: none; font-size: 14px; line-height: 1.5; transition: all 0.3s; } .note-textarea:focus { outline: none; border-color: #6a5af9; box-shadow: 0 0 0 3px rgba(106, 90, 249, 0.1); } .note-footer { padding: 10px 15px; display: flex; justify-content: flex-end; background: #f5f5f5; } .note-save { padding: 8px 16px; background: linear-gradient(135deg, #6a5af9, #d66efd); color: white; border: none; border-radius: 6px; cursor: pointer; font-size: 14px; font-weight: 500; transition: all 0.3s; box-shadow: 0 4px 10px rgba(106, 90, 249, 0.2); } .note-save:hover { transform: translateY(-2px); box-shadow: 0 6px 15px rgba(106, 90, 249, 0.3); } /* 阅读模式 */ .reading-mode-active { background-color: #f8f9fa !important; color: #333 !important; font-size: 18px !important; line-height: 1.7 !important; letter-spacing: 0.3px !important; } .reading-mode-active p, .reading-mode-active div { max-width: 900px !important; margin: 0 auto !important; padding: 15px 30px !important; } /* 拖动功能 */ .draggable { cursor: move; } /* 状态提示 */ .status-tip { position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%); background: rgba(0, 0, 0, 0.7); color: white; padding: 10px 20px; border-radius: 8px; z-index: 10000; font-size: 14px; opacity: 0; transition: opacity 0.3s; pointer-events: none; } .status-tip.show { opacity: 1; } /* 按钮动效 */ @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.05); } 100% { transform: scale(1); } } .feature-btn.active:before { animation: pulse 2s infinite; } /* 进度条 */ .progress-container { width: 100%; height: 6px; background: #f0f0f0; border-radius: 3px; overflow: hidden; margin-top: 5px; } .progress-bar { height: 100%; background: linear-gradient(90deg, #6a5af9, #d66efd); width: 0; transition: width 0.3s; } `; document.head.appendChild(style); } // 创建助手按钮 createHelperButton() { const btn = document.createElement('div'); btn.id = 'miaoke-helper-btn'; btn.innerHTML = '🐱'; btn.title = '点击打开喵课助手 - 学习更轻松'; document.body.appendChild(btn); // 添加点击事件 btn.addEventListener('click', () => { this.togglePanel(); }); // 创建提示标签 const tooltip = document.createElement('div'); tooltip.id = 'miaoke-tooltip'; tooltip.textContent = '点击打开喵课助手'; tooltip.style.position = 'fixed'; tooltip.style.right = '90px'; tooltip.style.top = '120px'; tooltip.style.background = 'white'; tooltip.style.color = '#333'; tooltip.style.padding = '8px 12px'; tooltip.style.borderRadius = '6px'; tooltip.style.boxShadow = '0 2px 10px rgba(0,0,0,0.1)'; tooltip.style.fontSize = '14px'; tooltip.style.zIndex = '9998'; tooltip.style.opacity = '0'; tooltip.style.transition = 'opacity 0.3s, right 0.3s'; tooltip.style.pointerEvents = 'none'; document.body.appendChild(tooltip); // 显示提示标签 btn.addEventListener('mouseenter', () => { tooltip.style.opacity = '1'; tooltip.style.right = '95px'; }); // 隐藏提示标签 btn.addEventListener('mouseleave', () => { tooltip.style.opacity = '0'; tooltip.style.right = '90px'; }); // 首次加载2秒后短暂显示提示 setTimeout(() => { tooltip.style.opacity = '1'; tooltip.style.right = '95px'; setTimeout(() => { tooltip.style.opacity = '0'; tooltip.style.right = '90px'; }, 3000); }, 2000); } // 创建主面板 createPanel() { // 主面板 const panel = document.createElement('div'); panel.id = 'miaoke-helper-panel'; panel.innerHTML = `

喵课助手 - ${this.siteName}

×
学习辅助功能
自动播放
阅读模式
笔记工具
速度调节
自动下一章
视频状态
当前状态: 未检测到视频
自动播放: 未启用
喵课资源推荐
邀请码: 0000 必填
网课自动化解决方案: 访问
更多学习工具: 查看
`; document.body.appendChild(panel); // 笔记面板 const notePanel = document.createElement('div'); notePanel.id = 'note-panel'; notePanel.innerHTML = `
学习笔记 ×
`; document.body.appendChild(notePanel); // 状态提示 const statusTip = document.createElement('div'); statusTip.className = 'status-tip'; statusTip.id = 'status-tip'; document.body.appendChild(statusTip); } // 监听历史记录变化,用于单页应用 listenToHistoryChanges() { // 监听 history.pushState 和 replaceState const originalPushState = history.pushState; const originalReplaceState = history.replaceState; history.pushState = function() { originalPushState.apply(this, arguments); // 触发自定义事件 window.dispatchEvent(new Event('locationchange')); }; history.replaceState = function() { originalReplaceState.apply(this, arguments); // 触发自定义事件 window.dispatchEvent(new Event('locationchange')); }; // 监听 popstate window.addEventListener('popstate', () => { window.dispatchEvent(new Event('locationchange')); }); // 在URL变化时检查视频 window.addEventListener('locationchange', () => { console.log('检测到页面导航,重新检查视频'); // 更新站点名称 this.siteName = this.detectSite(); // 短暂延迟后检查视频 setTimeout(() => { this.checkForVideo(); }, 1000); // 确保只有一个面板 this.ensureOnlyOnePanel(); }); } // 确保页面上只有一个面板 ensureOnlyOnePanel() { const panels = document.querySelectorAll('#miaoke-panel'); if (panels.length > 1) { console.log(`发现${panels.length}个面板,移除多余的`); // 保留第一个面板,移除其他面板 for (let i = 1; i < panels.length; i++) { panels[i].parentNode.removeChild(panels[i]); } } } // 检查视频并自动启用功能 checkForVideo() { const videos = document.querySelectorAll('video'); if (videos.length > 0) { console.log(`检测到${videos.length}个视频元素`); // 自动开启视频功能 if (document.getElementById('auto-play').classList.contains('active')) { this.autoPlayVideos(); } } } // 显示状态提示 showStatusTip(message, duration = 2000) { const tip = document.getElementById('status-tip'); tip.textContent = message; tip.classList.add('show'); setTimeout(() => { tip.classList.remove('show'); }, duration); } // 显示欢迎提示 showWelcomeNotification() { const notification = document.createElement('div'); notification.className = 'miaoke-notification'; notification.innerHTML = `
🌟 喵课助手欢迎您 🌟 ×

网课学习神器已准备就绪!

全自动学习辅助工具,让您轻松应对各类网络课程

📚 自动播放视频 - 无需手动点击下一节课程
⏱️ 视频加速 - 自由调节播放速度,节省学习时间
📝 笔记工具 - 轻松记录学习要点,提高效率
`; document.body.appendChild(notification); // 关闭按钮事件 const closeButtons = notification.querySelectorAll('.notification-close'); closeButtons.forEach(btn => { btn.addEventListener('click', () => { notification.style.animation = 'slideOutRight 0.5s forwards'; setTimeout(() => { notification.remove(); }, 500); }); }); // 分享按钮事件 const shareButton = notification.querySelector('#miaoke-welcome-share'); if (shareButton) { shareButton.addEventListener('click', () => { const shareText = '推荐一个超好用的网课神器「喵课助手」,可以视频加速、自动播放、一键笔记,一站式解决网课难题!安装地址:http://nb.zizizi.top'; const tempInput = document.createElement('textarea'); tempInput.style.position = 'absolute'; tempInput.style.left = '-9999px'; tempInput.value = shareText; document.body.appendChild(tempInput); tempInput.select(); try { document.execCommand('copy'); this.showTip('分享文本已复制到剪贴板,快去发给同学吧!', 3000); } catch (err) { this.showTip('复制失败,请手动复制分享文本', 3000); } document.body.removeChild(tempInput); }); } // 自动关闭计时器 - 延长时间确保用户看到 setTimeout(() => { if (document.body.contains(notification)) { notification.style.animation = 'slideOutRight 0.5s forwards'; setTimeout(() => { if (document.body.contains(notification)) { notification.remove(); } }, 500); } }, 20000); } // 分享喵课助手 shareHelper() { const url = 'http://nb.zizizi.top'; const title = '喵课助手 - 网课自动化学习工具'; const text = '🐱 喵课助手:自动播放、视频加速、笔记工具等功能,帮助您更好地学习!'; // 分享到微信 const wechatShare = document.createElement('div'); wechatShare.innerHTML = `

打开微信,扫描二维码分享给朋友

`; document.body.appendChild(wechatShare); // 分享到QQ const qqShare = document.createElement('div'); qqShare.innerHTML = `

打开QQ,扫描二维码分享给朋友

`; document.body.appendChild(qqShare); // 分享到微博 const weiboShare = document.createElement('div'); weiboShare.innerHTML = `

打开微博,扫描二维码分享给朋友

`; document.body.appendChild(weiboShare); // 分享到其他平台 const otherShare = document.createElement('div'); otherShare.innerHTML = `

复制链接,分享给朋友

`; document.body.appendChild(otherShare); } // 显示更新提示 showUpdateNotification(lastVersion) { const notification = document.createElement('div'); notification.className = 'miaoke-notification'; notification.innerHTML = `
🚀 喵课助手全新升级 🚀 ×

您的喵课助手已升级至 v${this.version}

我们带来了更多强大功能,让您的学习更高效!

性能优化 - 运行更快更稳定,支持更多课程平台
🔍 智能识别 - 自动适配不同平台的视频控件
🛠️ 界面升级 - 全新UI设计,操作更简便
`; document.body.appendChild(notification); // 关闭按钮事件 const closeButtons = notification.querySelectorAll('.notification-close'); closeButtons.forEach(btn => { btn.addEventListener('click', () => { notification.style.animation = 'slideOutRight 0.5s forwards'; setTimeout(() => { notification.remove(); }, 500); }); }); // 分享按钮事件 const shareButton = notification.querySelector('#miaoke-update-share'); if (shareButton) { shareButton.addEventListener('click', () => { const shareText = '喵课助手更新啦!现在支持更多平台,运行更稳定,UI更美观。这是我用过最好的网课学习工具,强烈推荐! http://nb.zizizi.top'; const tempInput = document.createElement('textarea'); tempInput.style.position = 'absolute'; tempInput.style.left = '-9999px'; tempInput.value = shareText; document.body.appendChild(tempInput); tempInput.select(); try { document.execCommand('copy'); this.showTip('更新分享文本已复制,快去告诉同学吧!', 3000); } catch (err) { this.showTip('复制失败,请手动复制分享文本', 3000); } document.body.removeChild(tempInput); }); } // 自动关闭计时器 setTimeout(() => { if (document.body.contains(notification)) { notification.style.animation = 'slideOutRight 0.5s forwards'; setTimeout(() => { if (document.body.contains(notification)) { notification.remove(); } }, 500); } }, 20000); } // 初始化功能 initFeatures() { // 获取保存的笔记 const savedNote = GM_getValue('miaoke_helper_note_' + window.location.href, ''); if (savedNote) { document.querySelector('.note-textarea').value = savedNote; } // 获取保存的设置 const savedSpeed = GM_getValue('miaoke_helper_speed', 1.5); document.getElementById('play-speed').value = savedSpeed; // 获取自动播放设置 const autoPlayEnabled = GM_getValue('miaoke_helper_autoplay', true); if (autoPlayEnabled) { document.getElementById('auto-play').classList.add('active'); this.enableAutoPlay(); } } // 绑定事件 setupEvents() { const self = this; // 主按钮点击 document.getElementById('miaoke-helper-btn').addEventListener('click', function() { const panel = document.getElementById('miaoke-helper-panel'); panel.classList.toggle('active'); }); // 关闭按钮 document.querySelectorAll('.helper-close').forEach(function(el) { el.addEventListener('click', function() { this.closest('#miaoke-helper-panel, #note-panel').classList.remove('active'); }); }); // 自动播放 document.getElementById('auto-play').addEventListener('click', function() { this.classList.toggle('active'); if (this.classList.contains('active')) { self.enableAutoPlay(); GM_setValue('miaoke_helper_autoplay', true); self.showStatusTip('已开启自动播放功能', 1500); } else { self.disableAutoPlay(); GM_setValue('miaoke_helper_autoplay', false); self.showStatusTip('已关闭自动播放功能', 1500); } }); // 阅读模式 document.getElementById('reading-mode').addEventListener('click', function() { this.classList.toggle('active'); document.body.classList.toggle('reading-mode-active'); }); // 笔记工具 document.getElementById('take-notes').addEventListener('click', function() { document.getElementById('note-panel').classList.toggle('active'); }); // 保存笔记 document.querySelector('.note-save').addEventListener('click', function() { const noteContent = document.querySelector('.note-textarea').value; GM_setValue('miaoke_helper_note_' + window.location.href, noteContent); self.showStatusTip('笔记已保存!', 1500); }); // 速度调节 document.getElementById('speed-control').addEventListener('click', function() { this.classList.toggle('active'); const speedSettings = document.getElementById('speed-settings'); speedSettings.style.display = speedSettings.style.display === 'none' ? 'block' : 'none'; }); // 应用速度 document.getElementById('apply-speed').addEventListener('click', function() { const speedValue = parseFloat(document.getElementById('play-speed').value); GM_setValue('miaoke_helper_speed', speedValue); self.applyVideoSpeed(speedValue); self.showStatusTip(`已将视频速度设为 ${speedValue}x`, 1500); }); // 自动下一章 document.getElementById('auto-next').addEventListener('click', function() { this.classList.toggle('active'); if (this.classList.contains('active')) { self.enableAutoNext(); self.showStatusTip('已开启自动下一章功能', 1500); } else { self.disableAutoNext(); self.showStatusTip('已关闭自动下一章功能', 1500); } }); // 拖动功能 this.enableDrag(document.querySelectorAll('.draggable')); } // 启用自动播放 enableAutoPlay() { // 立即尝试播放当前视频 this.autoPlayVideos(); // 更新自动播放状态 document.getElementById('autoplay-status').textContent = '已启用'; document.getElementById('autoplay-status').style.color = '#6a5af9'; // 监听 DOM 变化以捕捉新加载的视频 if (!this.mutationObserver) { this.mutationObserver = new MutationObserver((mutations) => { // 使用防抖,避免频繁调用 if (Date.now() - this.lastPlayTime > 1000) { this.autoPlayVideos(); this.lastPlayTime = Date.now(); } }); this.mutationObserver.observe(document.body, { childList: true, subtree: true }); } // 定时检查是否有需要播放的视频,降低检查频率 if (!this.autoPlayInterval) { this.autoPlayInterval = setInterval(() => { this.updateVideoStatus(); // 只在需要时才处理自动播放和弹窗 if (this.shouldTryAutoplay()) { this.autoPlayVideos(); this.handlePopupDialogs(); } }, 2000); // 增加间隔到2秒,减少干扰 } } // 判断是否应该尝试自动播放 shouldTryAutoplay() { // 获取所有视频元素 const videos = document.querySelectorAll('video'); if (videos.length === 0) return false; // 如果用户主动暂停,则不应该自动播放 if (this.isUserPaused) return false; // 检查是否有任何视频需要播放 let needsPlayback = false; videos.forEach(video => { // 只有当视频暂停且不是已结束状态时才需要播放 if (video.paused && !video.ended) { // 检查是否正在缓冲 if (video.readyState < 3) { // 正在缓冲,等待加载更多数据 return; } // 检查尝试次数,避免无限尝试 const videoId = video.src || video.currentSrc || video.id || 'unknown'; if (!this.playAttempts[videoId]) { this.playAttempts[videoId] = 0; } // 如果尝试次数过多,间隔至少30秒再试 if (this.playAttempts[videoId] > 5) { const lastAttempt = video.getAttribute('last-attempt-time') || 0; if (Date.now() - lastAttempt < 30000) { return; } // 重置尝试次数 this.playAttempts[videoId] = 0; } needsPlayback = true; } }); return needsPlayback; } // 实际处理自动播放的函数 autoPlayVideos() { // 获取所有视频元素 const videos = document.querySelectorAll('video'); if (videos.length > 0) { // 更新视频状态 document.getElementById('video-status').textContent = '已检测到视频'; document.getElementById('video-status').style.color = '#6a5af9'; // 播放每个视频 videos.forEach(video => { // 为视频添加事件监听器(如果尚未添加) if (!video.hasAttribute('miaoke-processed')) { // 添加播放错误处理 video.addEventListener('error', () => { console.log('视频播放出错'); this.showStatusTip('视频播放出错,尝试恢复...', 2000); setTimeout(() => this.clickPlayButton(), 500); }); // 添加进度更新 video.addEventListener('timeupdate', () => { this.updateVideoProgress(video); }); // 添加视频结束处理 video.addEventListener('ended', () => { if (document.getElementById('auto-next').classList.contains('active')) { setTimeout(() => this.findAndClickNextButton(), 1000); } }); // 添加用户交互检测 video.addEventListener('pause', () => { // 检测如果是用户手动暂停的 if (document.activeElement === video || Date.now() - this.lastPlayTime > 1000) { this.isUserPaused = true; console.log('检测到用户手动暂停'); // 五秒后重置用户暂停状态,允许系统再次尝试自动播放 setTimeout(() => { this.isUserPaused = false; }, 5000); } }); // 添加播放事件处理 video.addEventListener('play', () => { // 重置播放尝试次数 const videoId = video.src || video.currentSrc || video.id || 'unknown'; this.playAttempts[videoId] = 0; // 更新播放状态 this.isUserPaused = false; }); video.setAttribute('miaoke-processed', 'true'); } // 如果视频暂停且不是用户主动暂停 if (video.paused && !video.ended && !this.isUserPaused) { // 获取视频ID const videoId = video.src || video.currentSrc || video.id || 'unknown'; // 记录尝试时间 video.setAttribute('last-attempt-time', Date.now()); this.lastPlayTime = Date.now(); // 增加尝试次数 if (!this.playAttempts[videoId]) { this.playAttempts[videoId] = 0; } this.playAttempts[videoId]++; // 检查视频是否已缓冲足够数据 if (video.readyState >= 3) { // 先尝试点击播放按钮 const buttonClicked = this.clickPlayButton(); // 如果没有点击成功或者是第一次尝试,直接调用play() if (!buttonClicked || this.playAttempts[videoId] <= 1) { // 尝试直接播放视频元素 const playPromise = video.play(); // 处理可能的错误 if (playPromise !== undefined) { playPromise.catch(error => { console.log('自动播放失败,尝试备用方法:', error.message); // 备用方法:模拟用户交互后再尝试播放 if (this.playAttempts[videoId] < 3) { setTimeout(() => { // 短暂聚焦视频元素 video.focus(); // 模拟点击视频 video.click(); // 再次尝试播放 video.play().catch(e => { console.log('第二次播放尝试也失败:', e.message); // 最后的方法:尝试特定站点的解决方案 if (this.playAttempts[videoId] < 5) { this.trySiteSpecificAutoplay(); } }); }, 500); } }); } } } else { console.log('视频未完全加载,等待缓冲...'); } } // 应用当前设置的速度,但避免频繁设置 const currentTime = Date.now(); if (!video.lastSpeedApplied || currentTime - video.lastSpeedApplied > 5000) { const currentSpeed = parseFloat(document.getElementById('play-speed').value); if (video.playbackRate !== currentSpeed) { video.playbackRate = currentSpeed; video.lastSpeedApplied = currentTime; } } }); } else { // 没有视频的情况 document.getElementById('video-status').textContent = '未检测到视频'; document.getElementById('video-status').style.color = '#888'; // 重置进度条 const progressBar = document.getElementById('video-progress'); progressBar.style.width = '0%'; } } // 尝试特定网站的自动播放解决方案 trySiteSpecificAutoplay() { let success = false; switch(this.siteName) { case '超星学习通': // 超星特定方法 success = this.chaoxingSiteSpecific(); break; case '智慧树': // 智慧树特定方法 success = this.zhihuishuSiteSpecific(); break; case 'B站': // B站特定方法 success = this.bilibiliSiteSpecific(); break; default: // 通用方法,模拟空格键按下 try { document.dispatchEvent(new KeyboardEvent('keydown', { key: ' ', keyCode: 32, which: 32 })); document.dispatchEvent(new KeyboardEvent('keyup', { key: ' ', keyCode: 32, which: 32 })); console.log('已尝试模拟空格键播放'); success = true; } catch (e) { console.error('模拟空格键失败:', e); } break; } return success; } // 超星学习通特定解决方案 chaoxingSiteSpecific() { try { // 尝试查找并移除覆盖层 const overlays = document.querySelectorAll('.vjs-overlay, .ans-videoquiz'); overlays.forEach(overlay => overlay.remove()); // 尝试直接调用播放器的play方法 const playerObj = document.querySelector('#video_html5_api') || document.querySelector('.anv-video video'); if (playerObj && typeof playerObj.play === 'function') { playerObj.play(); console.log('超星学习通: 直接调用播放器方法'); return true; } // 尝试点击特定的播放按钮 const specificButton = document.querySelector('.vjs-play-control') || document.querySelector('.vjs-big-play-button'); if (specificButton) { specificButton.click(); console.log('超星学习通: 点击特定播放按钮'); return true; } return false; } catch (e) { console.error('超星学习通特定方法失败:', e); return false; } } // 智慧树特定解决方案 zhihuishuSiteSpecific() { try { // 尝试使用智慧树的视频对象 const videoContainer = document.querySelector('#mediaplayer'); if (videoContainer) { const playButton = videoContainer.querySelector('[class*="play-button"]') || videoContainer.querySelector('.controlsBar__play'); if (playButton) { playButton.click(); console.log('智慧树: 点击播放按钮'); return true; } } // 尝试移除对话框 const dialog = document.querySelector('.dialog-content'); if (dialog) { const okButton = dialog.querySelector('.ant-btn-primary'); if (okButton) { okButton.click(); console.log('智慧树: 关闭对话框'); return true; } } return false; } catch (e) { console.error('智慧树特定方法失败:', e); return false; } } // B站特定解决方案 bilibiliSiteSpecific() { try { // 尝试点击B站特定的播放按钮 const bButton = document.querySelector('.bpx-player-ctrl-play') || document.querySelector('.bilibili-player-video-btn-start'); if (bButton) { bButton.click(); console.log('B站: 点击播放按钮'); return true; } // 尝试使用B站的视频对象 const bVideo = document.querySelector('video.bilibili-player-video'); if (bVideo && typeof bVideo.play === 'function') { bVideo.play(); console.log('B站: 直接调用视频对象播放'); return true; } return false; } catch (e) { console.error('B站特定方法失败:', e); return false; } } // 查找并点击播放按钮 clickPlayButton() { // 基于网站类型查找播放按钮 let playButton = null; let clickSuccess = false; switch(this.siteName) { case '超星学习通': // 超星的播放按钮 playButton = document.querySelector('.vjs-play-control') || document.querySelector('.vjs-big-play-button') || document.querySelector('.playButton'); break; case '智慧树': // 智慧树的播放按钮 playButton = document.querySelector('.controlsBar__play') || document.querySelector('.controlsBar__bigPlay') || document.querySelector('[class*="play-button"]'); break; case 'B站': // B站的播放按钮 playButton = document.querySelector('.bpx-player-ctrl-play') || document.querySelector('.bilibili-player-video-btn-start'); break; default: // 通用播放按钮选择器 playButton = document.querySelector('button[title="播放"]') || document.querySelector('.vjs-play-control') || document.querySelector('[class*="play-button"]') || document.querySelector('[class*="play_button"]') || document.querySelector('[aria-label*="播放"]') || document.querySelector('[aria-label*="Play"]'); break; } // 如果找到了播放按钮且当前是暂停状态,则点击 if (playButton && (playButton.classList.contains('vjs-paused') || !playButton.classList.contains('vjs-playing'))) { try { // 首先尝试模拟鼠标事件 ['mouseover', 'mousedown', 'mouseup', 'click'].forEach(eventType => { const event = new MouseEvent(eventType, { bubbles: true, cancelable: true, view: window }); playButton.dispatchEvent(event); }); // 日志和状态记录 console.log('成功点击播放按钮'); clickSuccess = true; } catch (e) { console.error('点击播放按钮失败:', e); } } // 检查iframe内的视频播放按钮 if (!clickSuccess) { const iframes = document.querySelectorAll('iframe'); iframes.forEach(iframe => { try { if (iframe.contentDocument) { const iframePlayButton = iframe.contentDocument.querySelector('[class*="play-button"]') || iframe.contentDocument.querySelector('.vjs-play-control') || iframe.contentDocument.querySelector('[aria-label*="播放"]'); if (iframePlayButton) { try { ['mouseover', 'mousedown', 'mouseup', 'click'].forEach(eventType => { const event = new MouseEvent(eventType, { bubbles: true, cancelable: true, view: iframe.contentWindow }); iframePlayButton.dispatchEvent(event); }); console.log('成功点击iframe内的播放按钮'); clickSuccess = true; } catch (e) { console.error('点击iframe内播放按钮失败:', e); } } } } catch (e) { // 跨域iframe访问错误,正常情况 console.log('无法访问iframe内容 (可能是跨域限制)'); } }); } return clickSuccess; } // 处理弹窗和对话框 handlePopupDialogs() { // 处理常见的弹窗 const dialogSelectors = [ '.video-answer', // 超星的视频浏览会有的弹题 '.question-wrapper', // 智慧树的题目 '.dialog-test', // 一般测试弹窗 '.popbox', // 常见弹窗 '[class*="dialog"]', // 包含 dialog 的类 '[class*="popup"]', // 包含 popup 的类 '[class*="alert"]', // 包含 alert 的类 '[class*="modal"]', // 包含 modal 的类 // 特定平台的选择器 '.ans-videoquiz', // 超星弹题 '.ans-videoquiz-opt', // 超星选项 '.topic-item' // 智慧树题目 ]; // 尝试处理匹配到的弹窗 let dialogHandled = false; for (let selector of dialogSelectors) { const dialogs = document.querySelectorAll(selector); for (let dialog of dialogs) { if (dialog && (dialog.style.display !== 'none' && dialog.offsetParent !== null)) { // 尝试自动回答问题(对超星和智慧树常见的选择题) if (this.tryToAnswerQuestion(dialog)) { dialogHandled = true; continue; } // 尝试找到并点击关闭按钮 const closeButtons = dialog.querySelectorAll('button, .close, .btn-close, [class*="close"], [class*="cancel"], a[href="#"]'); for (let button of closeButtons) { if (button.innerText.includes('关闭') || button.innerText.includes('取消') || button.innerText.includes('继续') || button.innerText.includes('确定') || button.className.includes('close')) { button.click(); console.log('自动关闭了弹窗'); dialogHandled = true; break; } } if (dialogHandled) break; } } if (dialogHandled) break; } // 特殊处理:超星学习通的弹题 if (!dialogHandled && this.siteName === '超星学习通') { // 超星特定的弹题处理 const topicMenus = document.querySelectorAll('.topic-menu, .ans-videoquiz'); if (topicMenus.length > 0) { // 尝试寻找继续按钮 const continueButtons = document.querySelectorAll('div[onclick*="continue"], a:contains("继续学习"), .ans-videoquiz-submit'); if (continueButtons.length > 0) { continueButtons[0].click(); dialogHandled = true; } // 如果没找到继续按钮,尝试自动选择答案 if (!dialogHandled) { const options = document.querySelectorAll('.ans-videoquiz-opt'); if (options.length > 0) { // 默认选第一个 options[0].click(); // 寻找提交按钮 setTimeout(() => { const submitBtn = document.querySelector('.ans-videoquiz-submit'); if (submitBtn) submitBtn.click(); }, 500); } } } } return dialogHandled; } // 尝试自动回答问题 tryToAnswerQuestion(dialog) { // 检查是否有选项 const options = dialog.querySelectorAll('input[type="radio"], input[type="checkbox"], .ans-videoquiz-opt'); if (options.length === 0) return false; // 智慧树和超星平台的问题处理 if (this.siteName === '智慧树' || this.siteName === '超星学习通') { // 随机选择一个选项(或第一个) const option = options[0]; option.click(); // 查找提交按钮 setTimeout(() => { const submitBtns = dialog.querySelectorAll('button[type="submit"], .submit-btn, .ans-videoquiz-submit, [class*="submit"]'); if (submitBtns.length > 0) { submitBtns[0].click(); return true; } }, 500); } return false; } // 禁用自动播放 disableAutoPlay() { if (this.mutationObserver) { this.mutationObserver.disconnect(); this.mutationObserver = null; } if (this.autoPlayInterval) { clearInterval(this.autoPlayInterval); this.autoPlayInterval = null; } // 更新自动播放状态 document.getElementById('autoplay-status').textContent = '已禁用'; document.getElementById('autoplay-status').style.color = '#888'; } // 启用自动下一章 enableAutoNext() { if (this.autoNextInterval) { clearInterval(this.autoNextInterval); } this.autoNextInterval = setInterval(() => { const videos = document.querySelectorAll('video'); videos.forEach(video => { if (video.ended) { this.findAndClickNextButton(); } }); }, 2000); } // 禁用自动下一章 disableAutoNext() { if (this.autoNextInterval) { clearInterval(this.autoNextInterval); this.autoNextInterval = null; } } // 寻找并点击下一章按钮 findAndClickNextButton() { // 针对不同平台查找下一章按钮 let nextBtn = null; // 超星学习通 if (this.siteName === '超星学习通') { nextBtn = document.querySelector('.ans-job-icon[title="下一章"]') || document.querySelector('.nextChapter'); } // 智慧树 else if (this.siteName === '智慧树') { nextBtn = document.querySelector('.next-page-btn') || document.querySelector('.next-btn'); } // 智慧职教 else if (this.siteName === '智慧职教') { nextBtn = document.querySelector('.next_lesson') || document.querySelector('.next-lesson'); } // 其他平台的通用选择器 else { const possibleSelectors = [ '.next', '.next-btn', '.next-lesson', '.nextChapter', '[title="下一章"]', '[title="下一节"]', '[title="下一讲"]', 'a:contains("下一章")', 'a:contains("下一节")' ]; for (let selector of possibleSelectors) { nextBtn = document.querySelector(selector); if (nextBtn) break; } } if (nextBtn) { nextBtn.click(); console.log('已自动跳转至下一章'); } } // 设置视频速度 applyVideoSpeed(speed) { const videos = document.querySelectorAll('video'); videos.forEach(video => { video.playbackRate = speed; }); // 持续应用速度(防止视频网站重置) if (this.speedInterval) { clearInterval(this.speedInterval); } this.speedInterval = setInterval(() => { const videos = document.querySelectorAll('video'); videos.forEach(video => { if (video.playbackRate !== speed) { video.playbackRate = speed; } }); // 更新速度进度条 const speedProgressBar = document.getElementById('speed-progress'); if (speedProgressBar) { const speedPercent = Math.min(100, (speed / 16) * 100); speedProgressBar.style.width = `${speedPercent}%`; } // 在面板上显示当前速度 const statusText = document.getElementById('video-status'); if (statusText && statusText.textContent.includes('播放中')) { statusText.textContent = `播放中 (${speed}x)`; } }, 1000); // 显示状态提示 this.showStatusTip(`视频速度已设置为 ${speed}x`, 2000); } // 启用拖动功能 enableDrag(elements) { elements.forEach(el => { el.addEventListener('mousedown', (e) => { const target = el.closest('#miaoke-helper-panel, #note-panel, #miaoke-helper-btn'); if (!target) return; // 初始位置 const initialX = e.clientX; const initialY = e.clientY; const startLeft = target.offsetLeft; const startTop = target.offsetTop; // 移动处理函数 const moveHandler = (e) => { const dx = e.clientX - initialX; const dy = e.clientY - initialY; target.style.left = startLeft + dx + 'px'; target.style.top = startTop + dy + 'px'; }; // 释放处理函数 const upHandler = () => { document.removeEventListener('mousemove', moveHandler); document.removeEventListener('mouseup', upHandler); }; document.addEventListener('mousemove', moveHandler); document.addEventListener('mouseup', upHandler); }); }); } // 清理资源,用于页面卸载或重新初始化时 cleanup() { // 移除面板 const panel = document.getElementById('miaoke-panel'); if (panel) { panel.parentNode.removeChild(panel); } // 移除状态提示 const tips = document.querySelectorAll('.miaoke-status-tip'); tips.forEach(tip => { tip.parentNode.removeChild(tip); }); // 清理定时器 if (this.autoPlayInterval) { clearInterval(this.autoPlayInterval); this.autoPlayInterval = null; } if (this.speedInterval) { clearInterval(this.speedInterval); this.speedInterval = null; } // 断开突变观察器 if (this.mutationObserver) { this.mutationObserver.disconnect(); this.mutationObserver = null; } // 清除实例引用 window.miaokeHelperInstance = null; } // 更新视频状态 updateVideoStatus() { const videos = document.querySelectorAll('video'); if (videos.length > 0) { let anyPlaying = false; videos.forEach(video => { if (!video.paused && !video.ended) { anyPlaying = true; // 更新当前播放中的视频进度 this.updateVideoProgress(video); } }); const statusText = document.getElementById('video-status'); if (anyPlaying) { const currentSpeed = parseFloat(document.getElementById('play-speed').value); statusText.textContent = `播放中 (${currentSpeed}x)`; statusText.style.color = '#4CAF50'; } else if (videos[0].ended) { statusText.textContent = '已播放完毕'; statusText.style.color = '#FF9800'; } else { statusText.textContent = '已暂停'; statusText.style.color = '#F44336'; } } } // 更新视频进度条 updateVideoProgress(video) { if (!video) return; // 计算百分比 const percent = (video.currentTime / video.duration) * 100; const progressBar = document.getElementById('video-progress'); if (!isNaN(percent) && isFinite(percent)) { progressBar.style.width = `${percent}%`; // 更新速度进度条 const speedProgressBar = document.getElementById('speed-progress'); if (speedProgressBar) { const speedPercent = Math.min(100, (parseFloat(document.getElementById('play-speed').value) / 16) * 100); speedProgressBar.style.width = `${speedPercent}%`; } } } // 设置周期性提醒 setupPeriodicReminder() { const reminderInterval = 60 * 60 * 1000; // 1小时 setInterval(() => { this.showReminderNotification(); }, reminderInterval); } // 显示周期性提醒 showReminderNotification() { const notification = document.createElement('div'); notification.className = 'miaoke-notification'; notification.innerHTML = `
📣 喵课助手提醒 📣 ×

您已经学习了一段时间了,记得休息一下,保护眼睛和身体哦!

`; document.body.appendChild(notification); // 关闭按钮事件 const closeButtons = notification.querySelectorAll('.notification-close'); closeButtons.forEach(btn => { btn.addEventListener('click', () => { notification.style.animation = 'slideOutRight 0.5s forwards'; setTimeout(() => { notification.remove(); }, 500); }); }); // 分享按钮事件 const shareButton = notification.querySelector('#miaoke-reminder-share'); if (shareButton) { shareButton.addEventListener('click', () => { const shareText = '喵课助手提醒您:学习是一件辛苦的事情,记得休息一下,保护眼睛和身体哦!'; const tempInput = document.createElement('textarea'); tempInput.style.position = 'absolute'; tempInput.style.left = '-9999px'; tempInput.value = shareText; document.body.appendChild(tempInput); tempInput.select(); try { document.execCommand('copy'); this.showTip('分享文本已复制到剪贴板,快去发给同学吧!', 3000); } catch (err) { this.showTip('复制失败,请手动复制分享文本', 3000); } document.body.removeChild(tempInput); }); } // 自动关闭计时器 setTimeout(() => { if (document.body.contains(notification)) { notification.style.animation = 'slideOutRight 0.5s forwards'; setTimeout(() => { if (document.body.contains(notification)) { notification.remove(); } }, 500); } }, 20000); } } // 在DOMContentLoaded时检查,优先于load事件 document.addEventListener('DOMContentLoaded', () => { initializeHelper(); }); // 页面完全加载后再次检查(以防DOMContentLoaded中的检查有问题) window.addEventListener('load', () => { initializeHelper(); }); // 页面卸载时清理资源 window.addEventListener('beforeunload', () => { if (window.miaokeHelperInstance) { window.miaokeHelperInstance.cleanup(); } }); // 帮助器初始化函数 function initializeHelper() { // 防止短时间内多次初始化 if (window.miaokeHelperInitializing) { return; } window.miaokeHelperInitializing = true; setTimeout(() => { window.miaokeHelperInitializing = false; }, 2000); // 首先检查全局实例 if (window.miaokeHelperInstance) { console.log('喵课助手全局实例已存在,跳过初始化'); return; } // 检查是否在iframe中,只在顶层窗口创建 if (window !== window.top) { console.log('在iframe中,跳过创建喵课助手'); return; } // 检查localStorage中是否有记录 try { const initialized = localStorage.getItem('miaokeHelper_initialized'); const timestamp = localStorage.getItem('miaokeHelper_timestamp'); // 如果已初始化且时间在5秒内,则跳过 if (initialized === 'true' && timestamp && (Date.now() - parseInt(timestamp)) < 5000) { console.log('喵课助手最近已初始化,跳过'); return; } } catch (e) { console.log('无法读取localStorage'); } // 检查DOM中是否已有面板 const existingPanel = document.getElementById('miaoke-panel'); if (existingPanel) { console.log('页面已存在喵课助手面板'); return; } // 所有检查通过,创建新实例 console.log('创建新的喵课助手实例'); window.miaokeHelper = new MiaoKeHelper(); } // 立即检查是否应该初始化 if (document.readyState === 'complete' || document.readyState === 'interactive') { initializeHelper(); } })();